
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityMovementAI;
using MyTools;
using BaseScripts;
public enum EnemyState{
    Idle,
    ChasePlayer,
    LookForPlayer,
    GoBack,
    Dead,
}

[RequireComponent(typeof(Wander2Unit))]
[RequireComponent(typeof(SeekUnit))]
[RequireComponent(typeof(SeekPositionUnit))]
public class Enemy : Status
{

    [Header("攻击参数")]
    public float fAttackDamage = 10f;
    public float fAttackForce = 3f;
    public float fAttackDistance = 3f;
    public float fAttackCoolDown = 3f;
    public float fTryAtkEverySecend = 1f;
    public float fTryAtkProbility = 0.5f;// 50%概率进行攻击
    private Cooldown cd_Atk;
    private Cooldown cd_TryAtk;

    [Header("寻找玩家时长")]
    public float fLookForPlayerTime = 5f;
    private Cooldown cd_LookForPlayer;
    [Header("持续追踪玩家时长")]
    public float fChasePlayerTime = 5f;
    private Cooldown cd_ChasePlayer;
    private bool bKeepChasePlayer = false;


    [Header("运行时")]
    public GameObject playerGameObject;
    public EnemyState state = EnemyState.Idle;
    public Vector3 spawnPosition;

    private Wander2Unit wander2Unit;
    private SeekUnit seekUnit;
    private SeekPositionUnit seekPositionUnit;
    private Animator animator;

    # region "Unity原方法"

    protected override void Awake() {
        base.Awake();
        wander2Unit = GetComponent<Wander2Unit>();
        seekUnit = GetComponent<SeekUnit>();
        seekPositionUnit = GetComponent<SeekPositionUnit>();
        animator = GetComponentInChildren<Animator>();
    }

    protected override void Start() {
        base.Start();

        spawnPosition = transform.position;

        cd_LookForPlayer = new Cooldown(fLookForPlayerTime);
        cd_ChasePlayer = new Cooldown(fChasePlayerTime);
        cd_TryAtk = new Cooldown(fTryAtkEverySecend);
        cd_Atk = new Cooldown(fAttackCoolDown);
    }

    protected  override void Update() {
        base.Update();
        cd_LookForPlayer.Update(Time.deltaTime);
        cd_ChasePlayer.Update(Time.deltaTime);
        cd_TryAtk.Update(Time.deltaTime);
        cd_Atk.Update(Time.deltaTime);

        if(isAlive) StateUpdate();
    }

    # endregion


    # region "StateChange"

    private void StateUpdate(){
        if (state == EnemyState.ChasePlayer){
            if (cd_Atk.Check()) 
            if (Vector3.Distance(playerGameObject.transform.position, transform.position) < fAttackDistance){// TryATK
                if (cd_TryAtk.Check()){
                    cd_TryAtk.Used();
                    if (Random.Range(0f,1f) < fTryAtkProbility){
                        cd_Atk.Used();
                        //ATK
                        GetComponentInChildren<Animator>().SetTrigger("Atk");
                    }
                }
            }
        }
        if (state == EnemyState.LookForPlayer && cd_LookForPlayer.Check()){//寻找玩家时长结束, 返回
            seekPositionUnit.targetPosition = spawnPosition;
            ChangeState(EnemyState.GoBack);
        }
        if (state == EnemyState.GoBack){
            if (seekPositionUnit.IsArrived()){
                ChangeState(EnemyState.Idle);
            }
        }
        if(state == EnemyState.ChasePlayer && bKeepChasePlayer){
            if (cd_ChasePlayer.Check())//持续追击时长结束
            {
                ChangeState(EnemyState.LookForPlayer);
                bKeepChasePlayer = false;
            }
        }
    }

    /// <summary>
    /// called by enemy view collider on trigger enter
    /// </summary>
    /// <param name="gameObject"></param>
    public void ViewPlayer(GameObject gameObject){
        playerGameObject = gameObject;

        seekUnit.target = playerGameObject.transform;
        ChangeState(EnemyState.ChasePlayer);
    }

    /// <summary>
    /// called by enemy view collider on trigger exit
    /// </summary>
    public void LostInViewPlayer(){
        cd_ChasePlayer.Used();
        bKeepChasePlayer = true;
        seekPositionUnit.targetPosition = playerGameObject.transform.position;
    }

    /// <summary>
    /// called by enemy anim caller, when enemy is ready to attack
    /// </summary>
    public void PauseSeek(){
        seekUnit.SetStopMove(true);
    }

    /// <summary>
    /// called by enemy anim caller, when enemy attack finished
    /// </summary>
    public void ResumeSeek(){
        seekUnit.SetStopMove(false);
    }

    private void ChangeState(EnemyState newState){
        switch (newState)
        {
            case EnemyState.Idle:
                wander2Unit.SetActive(true);

                seekUnit.SetActive(false);
                seekPositionUnit.SetActive(false);
                break;

            case EnemyState.ChasePlayer:
                cd_ChasePlayer.CooldownImidiately();
                bKeepChasePlayer = false;
                seekUnit.SetActive(true);

                wander2Unit.SetActive(false);
                seekPositionUnit.SetActive(false);
                break;

            case EnemyState.LookForPlayer:
                cd_LookForPlayer.CooldownImidiately();
                seekPositionUnit.SetActive(true);

                wander2Unit.SetActive(false);
                seekUnit.SetActive(false);
                break;

            case EnemyState.GoBack:
                seekPositionUnit.SetActive(true);

                wander2Unit.SetActive(false);
                seekUnit.SetActive(false);
                break;

            case EnemyState.Dead:
                seekPositionUnit.SetActive(false);
                wander2Unit.SetActive(false);
                seekUnit.SetActive(false);
                break;


        }
        state = newState;
    }
    
    # endregion



    # region "攻击"

    /// <summary>
    /// called by enemy attack collider, to get the damage
    /// </summary>
    /// <returns></returns>
    public float GetAttackDamage(){
        return fAttackDamage * base.atkRate;
    }


    /// <summary>
    /// called by enemy attack collider, to get the attack force
    /// </summary>
    /// <returns></returns>
    public float GetAttackForce(){
        return fAttackForce * base.atkRate;
    }

    # endregion


    # region "重写继承函数"

    protected override void Dead()
    {
        base.Dead();
        animator.SetBool("Dead",true);
        
    }

    # endregion
}   

